package is.bean;

import java.sql.*;
import java.util.Collection;
import java.util.LinkedList;
import javax.ejb.*;
import javax.naming.InitialContext;
import javax.sql.DataSource;

/**
 *
 * @author aspr0
 */
public abstract class BeanRoutines
{
    protected static final String jdbcResource = "jdbc/isbd";
    protected DataSource dataSource;
    protected String tableName;
    protected EntityContext context;
    protected Integer id;
    protected boolean modified = false;

    /**
     * @see javax.ejb.EntityBean#setEntityContext(javax.ejb.EntityContext)
     */
    public void setEntityContext(EntityContext aContext)
    {
        context = aContext;

        try
        {
            InitialContext ic = new InitialContext();
            dataSource = (DataSource) ic.lookup(jdbcResource);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * @see javax.ejb.EntityBean#unsetEntityContext()
     */
    public void unsetEntityContext()
    {
        context = null;
    }

    /**
     * @see javax.ejb.EntityBean#ejbActivate()
     */
    public void ejbActivate()
    {
        id = (Integer) context.getPrimaryKey();
    }

    /**
     * @see javax.ejb.EntityBean#ejbPassivate()
     */
    public void ejbPassivate()
    {
        id = null;
    }

    /**
     * See EJB 2.0 and EJB 2.1 section 12.2.5
     */
    public Integer ejbFindByPrimaryKey(Integer primaryKey) throws SQLException, FinderException
    {
        Connection connection = null;
        PreparedStatement statement = null;

        try
        {
            connection = dataSource.getConnection();
            String sql = "select count(*) count from %s where id = ?";
            sql = String.format(sql, tableName);
            statement = connection.prepareStatement(sql);

            statement.setInt(1, primaryKey);
            ResultSet resultSet = statement.executeQuery();
            resultSet.next();

            Integer count = resultSet.getInt("count");

            if (count == 1)
            {
                return primaryKey;
            }
            else
            {
                throw new FinderException();
            }
        }
        finally
        {
            if (connection != null)
            {
                connection.close();
            }

            if (statement != null)
            {
                statement.close();
            }
        }
    }

    /**
     * Finds correct parents for hierarchy beans while updating. Prevents from cycling hierarchy tree.
     *
     * @param id
     * @return
     * @throws FinderException
     */
    public Collection ejbFindParentsAvailable(Integer id) throws FinderException
    {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        Collection<Integer> foundIds = new LinkedList<Integer>();
        try
        {
            String sql = "select id "
                    + "from " + tableName + " "
                    + "where id not in ("
                    + "select id "
                    + "from " + tableName + " "
                    + "start with id = ? "
                    + "connect by prior id = parentId)";
            connection = dataSource.getConnection();
            statement = connection.prepareStatement(sql);
            statement.setInt(1, id);
            resultSet = statement.executeQuery();
            while (resultSet.next())
            {
                foundIds.add(resultSet.getInt("id"));
            }
        }
        catch (SQLException e)
        {
            throw new FinderException();
        }
        finally
        {
            try
            {
                if (resultSet != null)
                {
                    resultSet.close();
                }
                if (statement != null)
                {
                    statement.close();
                }
                if (connection != null)
                {
                    connection.close();
                }
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
        }
        return foundIds;
    }

    /**
     * @see javax.ejb.EntityBean#ejbRemove()
     */
    public void ejbRemove() throws RemoveException
    {
        Connection connection = null;
        PreparedStatement statement = null;
        try
        {
            connection = dataSource.getConnection();
            String sql = "delete from " + tableName + " where id = ?";
            statement = connection.prepareStatement(sql);
            statement.setInt(1, id);
            statement.execute();
        }
        catch (SQLException e)
        {
            throw new RemoveException();
        }
        finally
        {
            try
            {
                if (statement != null)
                {
                    statement.close();
                }
                if (connection != null)
                {
                    connection.close();
                }
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
        }
    }

    protected void setStringNullDecide(PreparedStatement ps, int parameterIndex, String s) throws SQLException
    {
        if (s == null)
        {
            ps.setNull(parameterIndex, java.sql.Types.VARCHAR);
        }
        else
        {
            ps.setString(parameterIndex, s);
        }
    }

    protected void setIntNullDecide(PreparedStatement ps, int parameterIndex, Integer i) throws SQLException
    {
        if (i == null || i == 0)
        {
            ps.setNull(parameterIndex, java.sql.Types.INTEGER);
        }
        else
        {
            ps.setInt(parameterIndex, i);
        }
    }
}
